package com.bungarus.busi;

import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
import org.ehcache.config.units.MemoryUnit;
import org.ehcache.expiry.ExpiryPolicy;
import org.ehcache.spi.loaderwriter.CacheLoadingException;
import org.ehcache.spi.loaderwriter.CacheWritingException;

import java.time.Duration;
import java.util.function.Supplier;

/**
 * Created by tang on 2018/11/30.
 */
public class StatusContainer {
    private static final StatusContainer container = new StatusContainer();
    private static final String USR_ONLINE_STATUS = "user-online-status";
    private static final long CACHE_ENTRIES_COUNT = 10 * 1000 * 1000;
    private static final long CACHE_OFFHEAP_SIZE = 100;

    private static CacheManager cacheManager;
    private Cache<String, Integer> statusCache;

    private StatusContainer() {
        init();
    }

    private void init() {
        cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
                .withCache(USR_ONLINE_STATUS,
                        CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, Integer.class,
                                ResourcePoolsBuilder
                                        .heap(CACHE_ENTRIES_COUNT)
                                        .offheap(100, MemoryUnit.MB))
                                .withExpiry(new ExpiryPolicy<String, Integer>() {
                                    @Override
                                    public Duration getExpiryForCreation(String s, Integer integer) {
                                        return Duration.ofHours(24);
                                    }

                                    @Override
                                    public Duration getExpiryForAccess(String s, Supplier<? extends Integer> supplier) {
                                        return null;
                                    }

                                    @Override
                                    public Duration getExpiryForUpdate(String s, Supplier<? extends Integer> supplier, Integer integer) {
                                        return null;
                                    }
                                })
                                .build())
                .build(true);
        this.statusCache = cacheManager.getCache(USR_ONLINE_STATUS, String.class, Integer.class);
    }

    public static StatusContainer getInstance() {
        return container;
    }

    public static void close() {
        if(null != cacheManager) {
            cacheManager.close();
        }
    }

    public void put(String userId, Integer status) throws StatusContainerException {
        try {
            this.statusCache.put(userId, status);
        }
        catch (CacheWritingException e) {
            throw new StatusContainerException(e);
        }
    }

    public Integer get(String userId) throws StatusContainerException{
        Integer result;
        try {
            return result = this.statusCache.get(userId);
        }
        catch (CacheLoadingException e) {
            throw new StatusContainerException(e);
        }
    }
}
